{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 한글 단어 리트리버 튜닝"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "한글 형태소 분석기 라이브러리인 `kiwipiepy` 를 설치합니다.\n",
    "- [`kiwipiepy` 프로젝트 링크](https://github.com/bab2min/kiwipiepy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# API 키를 환경변수로 관리하기 위한 설정 파일\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# API 키 정보 로드\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LangSmith 추적을 시작합니다.\n",
      "[프로젝트명]\n",
      "CH10-Retriever\n"
     ]
    }
   ],
   "source": [
    "# LangSmith 추적을 설정합니다. https://smith.langchain.com\n",
    "# !pip install langchain-teddynote\n",
    "from langchain_teddynote import logging\n",
    "\n",
    "# 프로젝트 이름을 입력합니다.\n",
    "logging.langsmith(\"CH10-Retriever\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install kiwipiepy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from kiwipiepy import Kiwi\n",
    "\n",
    "kiwi = Kiwi()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "토큰화를 진행합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Token(form='안녕', tag='NNG', start=0, len=2),\n",
       " Token(form='하', tag='XSA', start=2, len=1),\n",
       " Token(form='세요', tag='EF', start=3, len=2),\n",
       " Token(form='?', tag='SF', start=5, len=1),\n",
       " Token(form='형태소', tag='NNG', start=7, len=3),\n",
       " Token(form='분석기', tag='NNG', start=11, len=3),\n",
       " Token(form='키위', tag='NNG', start=15, len=2),\n",
       " Token(form='이', tag='VCP', start=17, len=1),\n",
       " Token(form='ᆸ니다', tag='EF', start=17, len=3)]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "kiwi.tokenize(\"안녕하세요? 형태소 분석기 키위입니다\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 다양한 문장으로 테스트"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.retrievers import EnsembleRetriever\n",
    "from langchain_community.retrievers import BM25Retriever\n",
    "from langchain_core.documents import Document\n",
    "from langchain.vectorstores import FAISS\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "\n",
    "docs = [\n",
    "    Document(\n",
    "        page_content=\"금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"금보험은 저축성과를 극대화합니다. 특히 노후 대비 저축에 유리하게 구성되어 있습니다.\"\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\"\n",
    "    ),\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "금융 보험 은 장기 적 이 ᆫ 자산 관리 와 위험 대비 를 목적 으로 고안 되 ᆫ 금융 상품 이 ᆸ니다 .\n",
      "금융 저축 보험 은 규칙 적 이 ᆫ 저축 을 통하 어 목돈 을 마련 하 ᆯ 수 있 으며 , 생명 보험 기능 도 겸비 하 고 있 습니다 .\n",
      "저축 금융 보험 은 저축 과 금융 을 통하 어 목돈 마련 에 도움 을 주 는 보험 이 ᆸ니다 . 또한 , 사망 보장 기능 도 제공 하 ᆸ니다 .\n",
      "금융 저 축산물 보험 은 장기 적 이 ᆫ 저축 목적 과 더불 어 , 축산물 제공 기능 을 갖추 고 있 는 특별 금융 상품 이 ᆸ니다 .\n",
      "금융 단 폭격 보험 은 저축 은 커녕 위험 대비 에 초점 을 맞추 ᆫ 상품 이 ᆸ니다 . 높 은 위험 을 감수 하 고자 하 는 고객 에게 적합 하 ᆸ니다 .\n",
      "금 보험 은 저축 성과 를 극대 화 하 ᆸ니다 . 특히 노후 대비 저축 에 유리 하 게 구성 되 어 있 습니다 .\n",
      "금융 보 씨 험하 ᆫ 말 좀 하 지 말 시 고 , 저축 이나 좀 하 시 던가요 . 뭐 가 그리 급하 시 ᆫ지 모르 겠 네요 .\n"
     ]
    }
   ],
   "source": [
    "for doc in docs:\n",
    "    print(\" \".join([token.form for token in kiwi.tokenize(doc.page_content)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 토큰화 함수를 생성\n",
    "def kiwi_tokenize(text):\n",
    "    return [token.form for token in kiwi.tokenize(text)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 실험: 다양한 종류의 검색기를 사용하여 검색 결과를 비교"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "bm25 = BM25Retriever.from_documents(docs)\n",
    "\n",
    "kiwi_bm25 = BM25Retriever.from_documents(docs, preprocess_func=kiwi_tokenize)\n",
    "\n",
    "faiss = FAISS.from_documents(docs, OpenAIEmbeddings()).as_retriever()\n",
    "\n",
    "bm25_faiss_73 = EnsembleRetriever(\n",
    "    retrievers=[bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.7, 0.3],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "bm25_faiss_37 = EnsembleRetriever(\n",
    "    retrievers=[bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.3, 0.7],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "kiwibm25_faiss_73 = EnsembleRetriever(\n",
    "    retrievers=[kiwi_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.7, 0.3],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "kiwibm25_faiss_37 = EnsembleRetriever(\n",
    "    retrievers=[kiwi_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.3, 0.7],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "\n",
    "retrievers = {\n",
    "    \"bm25\": bm25,\n",
    "    \"kiwi_bm25\": kiwi_bm25,\n",
    "    \"faiss\": faiss,\n",
    "    \"bm25_faiss_73\": bm25_faiss_73,\n",
    "    \"bm25_faiss_37\": bm25_faiss_37,\n",
    "    \"kiwi_bm25_faiss_73\": kiwibm25_faiss_73,\n",
    "    \"kiwi_bm25_faiss_37\": kiwibm25_faiss_37,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_search_results(retrievers, query):\n",
    "    print(f\"Query: {query}\")\n",
    "    for name, retriever in retrievers.items():\n",
    "        print(f\"{name}    \\t: {retriever.invoke(query)[0].page_content}\")\n",
    "    print(\"===\" * 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "검색 결과를 출력합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Query: 금융보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 금융 보험\n",
      "bm25    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 금융저축보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "============================================================\n",
      "Query: 축산물 보험\n",
      "bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "faiss    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 저축금융보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kiwi_bm25_faiss_37    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "============================================================\n",
      "Query: 금융보씨 개인정보 조회\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n"
     ]
    }
   ],
   "source": [
    "print_search_results(retrievers, \"금융보험\")\n",
    "print_search_results(retrievers, \"금융 보험\")\n",
    "print_search_results(retrievers, \"금융저축보험\")\n",
    "print_search_results(retrievers, \"축산물 보험\")\n",
    "print_search_results(retrievers, \"저축금융보험\")\n",
    "print_search_results(retrievers, \"금융보씨 개인정보 조회\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Konlpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install konlpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from konlpy.tag import Kkma, Okt, Komoran, Hannanum\n",
    "from kiwipiepy import Kiwi\n",
    "\n",
    "kkma = Kkma()\n",
    "okt = Okt()\n",
    "komoran = Komoran()\n",
    "hannanum = Hannanum()\n",
    "kiwi = Kiwi()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "text = \"안녕하세요? 형태소 분석기 테스트베드입니다.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "kkma    : \t안녕 하 세요 ? 형태소 분석기 테스트 베드 이 ㅂ니다 .\n",
      "okt     : \t안녕하세요 ? 형태소 분석 기 테스트 베드 입니다 .\n",
      "komoran : \t안녕하세요 ? 형태소 분석기 테스트 베드 이 ㅂ니다 .\n",
      "hannanum: \t안녕 하 세 요 ? 형태소 분석기 테스트베드 이 ㅂ니다 .\n",
      "kiwi    : \t안녕 하 세요 ? 형태소 분석기 테스트 베드 이 ᆸ니다 .\n"
     ]
    }
   ],
   "source": [
    "print(\"kkma    : \\t\", end=\"\")\n",
    "print(\" \".join(kkma.morphs(text)))\n",
    "print(\"okt     : \\t\", end=\"\")\n",
    "print(\" \".join(okt.morphs(text)))\n",
    "print(\"komoran : \\t\", end=\"\")\n",
    "print(\" \".join(komoran.morphs(text)))\n",
    "print(\"hannanum: \\t\", end=\"\")\n",
    "print(\" \".join(hannanum.morphs(text)))\n",
    "print(\"kiwi    : \\t\", end=\"\")\n",
    "print(\" \".join([tok.form for tok in kiwi.tokenize(text)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "kiwi.add_user_word(\"안녕하세요 반가워요\", \"NNP\", 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "kiwi    : \t안녕 하 세요 ? 형태소 분석기 테스트 베드 이 ᆸ니다 .\n"
     ]
    }
   ],
   "source": [
    "print(\"kiwi    : \\t\", end=\"\")\n",
    "print(\" \".join([tok.form for tok in kiwi.tokenize(text)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def kkma_tokenize(text):\n",
    "    return [token for token in kkma.morphs(text)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "def okt_tokenize(text):\n",
    "    return [token for token in okt.morphs(text)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "kkma_bm25 = BM25Retriever.from_documents(docs, preprocess_func=kkma_tokenize)\n",
    "kkma_bm25_faiss_73 = EnsembleRetriever(\n",
    "    retrievers=[kkma_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.7, 0.3],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "kkma_bm25_faiss_37 = EnsembleRetriever(\n",
    "    retrievers=[kkma_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.3, 0.7],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "\n",
    "okt_bm25 = BM25Retriever.from_documents(docs, preprocess_func=okt_tokenize)\n",
    "okt_bm25_faiss_73 = EnsembleRetriever(\n",
    "    retrievers=[okt_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.7, 0.3],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "okt_bm25_faiss_37 = EnsembleRetriever(\n",
    "    retrievers=[okt_bm25, faiss],  # 사용할 검색 모델의 리스트\n",
    "    weights=[0.3, 0.7],  # 각 검색 모델의 결과에 적용할 가중치\n",
    "    search_type=\"mmr\",  # 검색 결과의 다양성을 증진시키는 MMR 방식을 사용\n",
    ")\n",
    "\n",
    "retrievers = {\n",
    "    \"bm25\": bm25,\n",
    "    \"kiwi_bm25\": kiwi_bm25,\n",
    "    \"faiss\": faiss,\n",
    "    \"bm25_faiss_73\": bm25_faiss_73,\n",
    "    \"bm25_faiss_37\": bm25_faiss_37,\n",
    "    \"kiwi_bm25_faiss_73\": kiwibm25_faiss_73,\n",
    "    \"kiwi_bm25_faiss_37\": kiwibm25_faiss_37,\n",
    "    \"kkma_bm25\": kkma_bm25,\n",
    "    \"kkma_bm25_faiss_73\": kkma_bm25_faiss_73,\n",
    "    \"kkma_bm25_faiss_37\": kkma_bm25_faiss_37,\n",
    "    \"okt_bm25\": okt_bm25,\n",
    "    \"okt_bm25_faiss_73\": okt_bm25_faiss_73,\n",
    "    \"okt_bm25_faiss_37\": okt_bm25_faiss_37,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Query: 금융보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kkma_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kkma_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "okt_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "okt_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 금융 보험\n",
      "bm25    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kkma_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kkma_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "okt_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_73    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "okt_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 금융저축보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "kkma_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_37    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "okt_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_37    \t: 금융저축보험은 규칙적인 저축을 통해 목돈을 마련할 수 있으며, 생명보험 기능도 겸비하고 있습니다.\n",
      "============================================================\n",
      "Query: 축산물 보험\n",
      "bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "faiss    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kiwi_bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kkma_bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kkma_bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "kkma_bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "okt_bm25    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "okt_bm25_faiss_73    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "okt_bm25_faiss_37    \t: 금융저축산물보험은 장기적인 저축 목적과 더불어, 축산물 제공 기능을 갖추고 있는 특별 금융 상품입니다.\n",
      "============================================================\n",
      "Query: 저축금융보험\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "faiss    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "bm25_faiss_73    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kiwi_bm25_faiss_37    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "kkma_bm25_faiss_37    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_73    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "okt_bm25_faiss_37    \t: 저축금융보험은 저축과 금융을 통해 목돈 마련에 도움을 주는 보험입니다. 또한, 사망 보장 기능도 제공합니다.\n",
      "============================================================\n",
      "Query: 금융보씨 개인정보 조회\n",
      "bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "faiss    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "bm25_faiss_37    \t: 금융단폭격보험은 저축은 커녕 위험 대비에 초점을 맞춘 상품입니다. 높은 위험을 감수하고자 하는 고객에게 적합합니다.\n",
      "kiwi_bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kiwi_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "kkma_bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kkma_bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "kkma_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "okt_bm25    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "okt_bm25_faiss_73    \t: 금융보씨 험한말 좀 하지마시고, 저축이나 좀 하시던가요. 뭐가 그리 급하신지 모르겠네요.\n",
      "okt_bm25_faiss_37    \t: 금융보험은 장기적인 자산 관리와 위험 대비를 목적으로 고안된 금융 상품입니다.\n",
      "============================================================\n"
     ]
    }
   ],
   "source": [
    "print_search_results(retrievers, \"금융보험\")\n",
    "print_search_results(retrievers, \"금융 보험\")\n",
    "print_search_results(retrievers, \"금융저축보험\")\n",
    "print_search_results(retrievers, \"축산물 보험\")\n",
    "print_search_results(retrievers, \"저축금융보험\")\n",
    "print_search_results(retrievers, \"금융보씨 개인정보 조회\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-kr-lwwSZlnu-py3.11",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
